package com.kly.sc.api.application.controller.config;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.StringUtils;
import com.google.common.collect.Maps;
import com.jsoniter.JsonIterator;
import com.jsoniter.any.Any;
import com.kly.sc.api.application.annos.SignIgnore;
import com.kly.sc.api.application.annos.VisitorAccessible;
import com.kly.sc.api.application.config.AppConfigs;
import com.kly.sc.api.application.config.UserRightsConfig;
import com.kly.sc.api.application.consts.Constants;
import com.kly.sc.api.application.controller.config.request.ConfigRequest;
import com.kly.sc.api.application.controller.config.request.CustomerServiceVo;
import com.kly.sc.api.application.controller.config.request.IosConfigRequest;
import com.kly.sc.api.application.enums.ConfigsType;
import com.kly.sc.api.application.enums.SwitchTypeEnum;
import com.kly.sc.api.application.helper.RequestLocalInfo;
import com.kly.sc.api.application.service.system.AppConfigApiService;
import com.kly.sc.api.application.utils.Result;
import com.kly.sc.api.infras.app.RequestBasicInfo;
import com.kly.user.dto.AdJustUserMappingReq;
import com.kly.user.dto.AppInfoDto;
import com.kly.user.dto.StoreAppsflyerUserMappingReq;
import com.kly.user.dto.UserInfoDto;
import com.kly.user.enums.ResultStatus;
import com.kly.user.enums.UserType;
import com.kly.user.service.AdjustService;
import com.kly.user.service.AppsflyerService;
import com.kly.user.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/app/")
@Api(value = "/api/app/", tags = "app开关配置")
public class ConfigController extends AppConfigs {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @NacosValue(value = "${newcomer.welcomepack.pop.countdown}", autoRefreshed = true)
    private String welcomePackPopCountdown;
    @NacosValue(value = "${ios.switch:[{\"version\":\"1.2.4\",\"switchFlag\":0}]}", autoRefreshed = true)
    private String iosSwitch;

    @Resource
    UserRightsConfig userRightsConfig;
    @Resource
    private UserService userService;
    @Resource
    private AdjustService adjustService;
    @Resource
    AppsflyerService appsflyerService;
    @Resource
    private AppConfigApiService appConfigApiService;
    /**
     * 开关打开
     */
    private final static Integer switchEnable = 1;


    /**
     * ios专用
     */
    @SignIgnore
    @VisitorAccessible
    @ResponseBody
    @PostMapping("/ios/switch")
    public Response iosSwitch(@RequestBody IosConfigRequest iosConfigRequest) {
        final RequestBasicInfo requestBasicInfo = RequestLocalInfo.getRequestBasicInfo();
        final String version = requestBasicInfo.getAppVersionName();

        if (iosConfigRequest.getType() == 0) {
            final com.alibaba.fastjson.JSONArray jsonArray = com.alibaba.fastjson.JSONArray.parseArray(iosSwitch);
            final Integer switchFlag = jsonArray.parallelStream().filter(o -> {
                JSONObject obj = (JSONObject) o;
                return Objects.equals(obj.getString("version"), version);
            }).map(o -> {
                JSONObject obj = (JSONObject) o;
                return obj.getIntValue("switchFlag");
            }).findFirst().orElse(1);
            return Response.ok(switchFlag);
        }

        return Response.ok();
    }

    /**
     * 获取服务配置相关信息
     */
    @SignIgnore
    @VisitorAccessible
    @ResponseBody
    @GetMapping("/all/configs")
    public Response allConfigs() {
        final RequestBasicInfo requestBasicInfo = RequestLocalInfo.getRequestBasicInfo();
        final String appCode = requestBasicInfo.getAppCode();
        final String appVersion = requestBasicInfo.getAppVersion();
        final HashMap<String, Object> configs = Maps.newHashMap();


        // 获取客服配置
        List<JSONObject> customerService = geCustomerService(ConfigRequest.toConfigRequest(ConfigsType.customerService.getType()));
        configs.put("customerService", customerService);

        // 获取协议
        final Map<String, String> agreement = userRightsConfig.getAgreement();
        configs.put("agreement", agreement);


        // pp/pv开关
        final JSONArray ppAndPvConfigArray = JSONUtil.parseArray(getPPVSwitch(appCode));
        final boolean match = ppAndPvConfigArray.stream().anyMatch(o -> {
            cn.hutool.json.JSONObject obj = (cn.hutool.json.JSONObject) o;
            if (requestBasicInfo.getAppVersionName().equals(obj.getStr("versionCode")) && requestBasicInfo.getAppVersion().equals(obj.getStr("versionSerialNo"))) {
                return obj.getInt("enableFlag").equals(switchEnable);
            }
            return Boolean.FALSE;
        });

        configs.put("photoShowUnableFlag", Boolean.FALSE);
        if (match) {
            configs.put("photoShowUnableFlag", Boolean.TRUE);
        }

        // flashchat消息
        final JSONArray flashchatMessages = JSONUtil.parseArray(getFlashchatMessages(appCode));
        Random rand = new Random();
        int randomNumber = rand.nextInt(flashchatMessages.size());
        final String flashchatMsg = (String)flashchatMessages.get(randomNumber);
        configs.put("flashchatMsg", flashchatMsg);

        // 登陆渠道
        configs.put("channel", getLoginChannel(appCode, appVersion));

        // 首页背景
        configs.put("homepageBgm", getHomePageBgm(appCode));
        return Response.ok(configs);
    }

    /**
     * 根据枚举类型获取开关配置信息
     * <p>
     * 版本记录：
     * <p>
     * 【meboo-v3.2】【更新】configsType:pp_pv_showUnable 增加新手礼包开关等配置
     */
    @SignIgnore
    @VisitorAccessible
    @ResponseBody
    @RequestMapping(value = "/configs", method = RequestMethod.POST)
    @ApiOperation("【meboo-v3.2】【更新】根据枚举类型获取开关配置信息")
    public Response appConfigs(@RequestBody ConfigRequest configRequest) {
        final RequestBasicInfo requestBasicInfo = RequestLocalInfo.getRequestBasicInfo();
        String appCode = requestBasicInfo.getAppCode();
        final String appVersion = requestBasicInfo.getAppVersion();

        ConfigsType configsType = ConfigsType.fromType(configRequest.getCode());
        switch (Objects.requireNonNull(configsType)) {
            case customerService:

                return Response.ok(getCustomerServiceList(configRequest, appCode));

            case agreement:

                // 前端登陆之前调用时，不传token，本次调用作为app激活埋点
                final String token = requestBasicInfo.getToken();
                if (StringUtils.isEmpty(token)) {
                    storeAppsFlyerInfo(configRequest);
                }
                return Response.ok(getAgreement(appCode));

            case pp_pv_showUnable:
                //默认关闭走nacos，开启走后台管理配置
                return getPPVControlConfigs(requestBasicInfo);

            case flashchat_message:
                final JSONArray flashchatMessages = JSONUtil.parseArray(getFlashchatMessages(appCode));
                Random rand = new Random();
                int randomNumber = rand.nextInt(flashchatMessages.size());
                return Response.ok(flashchatMessages.get(randomNumber));

            case loginChannel:
                return Response.ok().putData(getLoginChannel(appCode, appVersion));

            case homepage_bgm:
                return Response.ok().putData(getHomePageBgm(appCode));

            case order_snapshot_log:
                return Response.ok().putData(getOrderSnapshotAddSwitch(appCode));

            default:
                return Response.error();
        }
    }

    private Response getPPVControlConfigs(RequestBasicInfo requestBasicInfo) {
        String appCode = requestBasicInfo.getAppCode();
        if (getSwitchManageAdmin(appCode)) {
            Map<String, Object> result = Maps.newHashMap();
            result.put("photoShowUnableFlag", appConfigApiService.getSwitch(SwitchTypeEnum.PP_PV, requestBasicInfo));
            result.put("newcomerGiftFlag", appConfigApiService.getSwitch(SwitchTypeEnum.NEWCOMER_GIFT, requestBasicInfo));
            result.put("newcomerGiftPopSecs", welcomePackPopCountdown != null ? Integer.parseInt(welcomePackPopCountdown) : Constants.DEFAULT_WELCOME_PACK_POP_COUNTDOWN);
            return Response.ok(result);
        }else{
            Map<String, Object> result = Maps.newHashMap();
            if (StringUtils.isEmpty(getPPVSwitch(appCode))) {
                result.put("photoShowUnableFlag", Boolean.FALSE);
                return Response.ok(result);
            }

            final JSONArray ppAndPvConfigArray = JSONUtil.parseArray(getPPVSwitch(appCode));
            if (CollectionUtils.isEmpty(ppAndPvConfigArray)) {
                result.put("photoShowUnableFlag", Boolean.FALSE);
                return Response.ok(result);
            }
            /**
             * api请求入参：{"appCode":"sparksy","applicationID":"com.kly.meboo","appVersion":24,"appVersionName":"2.0.9","appSource":"1","token":""}
             * 后台管理系统pp.pv 配置： [{"serialNo":"1","swithType":1,"appCode":"sparky","appName":"meboo","source":"android","versionCode":"2.0.1","versionSerialNo":"2","enableFlag":0,"switchKey":"pp.pv","switchName":"pp&pv"}]
             */

            final boolean match = ppAndPvConfigArray.stream().anyMatch(o -> {
                cn.hutool.json.JSONObject obj = (cn.hutool.json.JSONObject) o;
                if (appCode.equals(obj.getStr("appCode")) && requestBasicInfo.getAppVersionName().equals(obj.getStr("versionCode")) && requestBasicInfo.getAppVersion().equals(obj.getStr("versionSerialNo"))) {
                    return obj.getInt("enableFlag").equals(switchEnable);
                }
                return Boolean.FALSE;
            });
            if (match) {
                result.put("photoShowUnableFlag", Boolean.TRUE);
                return Response.ok(result);
            }
            result.put("photoShowUnableFlag", Boolean.FALSE);
            return Response.ok(result);
        }
    }

    /**
     * 返回客服列表
     */
    private List<CustomerServiceVo> getCustomerServiceList(ConfigRequest configRequest, String appCode) {
        Response<List<UserInfoDto>> userByUserTypeResp = userService.getUserByUserType(String.valueOf(UserType.CUSTOMER_SERVICE.getType()));
        if (userByUserTypeResp.isSuccess() && userByUserTypeResp.getData() != null) {
            List<UserInfoDto> customerList = userByUserTypeResp.getData();
            if (CollectionUtils.isNotEmpty(customerList)) {
                return customerList.stream()/*.filter(o -> Objects.equals(appCode, o.getAppCode()))*/
                        .map(o -> CustomerServiceVo.toVo(o, configRequest.getCode())).collect(Collectors.toList());
            }
        }
        return Collections.EMPTY_LIST;
    }


    private void storeAppsFlyerInfo(ConfigRequest request) {
        if (StringUtils.isNotEmpty(request.getAdid())) {
            // TODO: 2024/1/13
            try {
                String content = request.getChannel();
                final JSONObject contentJson = JSONObject.parseObject(content);

                String channel = contentJson.getString("network");
                final String campaign = contentJson.getString("campaign");
                try {
                    Any fbInstallReferrer = JsonIterator.deserialize(content).get("fbInstallReferrer");
                    channel = JsonIterator.deserialize(fbInstallReferrer.toString()).get("fb_install_referrer_publisher_platform").toString();
                } catch (Exception e) {
                    logger.error("==storeAppsFlyerInfo 解析渠道有异常 ==");
                }

                final String af_adset = contentJson.getString("adgroup");
                final String af_ad = contentJson.getString("creative");

                final AdJustUserMappingReq req = AdJustUserMappingReq.builder().adid(request.getAdid())
                        .channel(channel).campaign(campaign).afAdset(af_adset).afAd(af_ad).build();
                adjustService.updateAdjustInfo(req);
            } catch (Exception e) {
                logger.error("storeAppsFlyerInfoFailed, request:{}", JSONObject.toJSONString(request));
            }

        } else {
            try {
                final String appsFlyerUID = request.getAppsFlyerUid();
                String content = request.getChannel();
                if (StringUtils.isEmpty(content)) {
                    content = RequestLocalInfo.getRequestBasicInfo().getChannel();
                }

                if (StringUtils.isNotEmpty(appsFlyerUID)) {
                    StoreAppsflyerUserMappingReq.StoreAppsflyerUserMappingReqBuilder builder = StoreAppsflyerUserMappingReq.builder().appflyersId(appsFlyerUID);
                    if (StringUtils.isNotEmpty(content) && JSONUtil.isJson(content)) {
                        final JSONObject contentJson = JSONObject.parseObject(content);
                        final String af_channel = contentJson.getString("af_channel");
                        final String campaign = contentJson.getString("campaign");
                        final String af_adset = contentJson.getString("af_adset");
                        final String af_ad = contentJson.getString("af_ad");

                        builder.channel(af_channel).content(content).campaign(campaign).afAdset(af_adset).afAd(af_ad).launchTime(new Date()).build();

                    } else if (StringUtils.isNotEmpty(content) && !JSONUtil.isJson(content)) {
                        builder.channel(content).launchTime(new Date()).build();
                    } else {
                        builder.launchTime(new Date()).build();
                    }
                    appsflyerService.queryOrStoreIfNotExists(builder.build());
                }
            } catch (Exception e) {
                logger.error("storeAppsFlyerInfoFailed, request:{}", JSONObject.toJSONString(request));
            }
        }


    }

    /**
     * app升级控制
     */
    @SignIgnore
    @ResponseBody
    @RequestMapping("/upgradation")
    public Response appConfig(String appCode, Integer versionCode) {
        final RequestBasicInfo requestBasicInfo = RequestLocalInfo.getRequestBasicInfo();

        appCode = requestBasicInfo.getAppCode();
        versionCode = Integer.valueOf(requestBasicInfo.getAppVersion());

        Map<String, Map<String, String>> appConfig = userRightsConfig.getAppConfig();
        Map<String, String> codeConfig = appConfig.get(requestBasicInfo.getAppCode());

        logger.info("appCode: {} , versionCode: {}, codeConfig {}", appCode, versionCode, codeConfig);
        if (CollectionUtils.isNotEmpty(codeConfig)) {
            AppInfoDto appInfoDto = new AppInfoDto();
            appInfoDto.setAppCode(appCode);
            if (versionCode >= Integer.parseInt(codeConfig.get("versionCode"))) {
                appInfoDto.setUpdateFlag(false);
            } else {
                appInfoDto.setUpdateFlag(true);
                appInfoDto.setUpdateType(Integer.parseInt(codeConfig.get("type")));
                appInfoDto.setAppStoreUrl(codeConfig.get("storeUrl"));
                appInfoDto.setOtherPlatforms(codeConfig.get("otherPlatforms"));
                appInfoDto.setUpGradationDesc(codeConfig.get("upGradationDesc"));

            }
            return Response.ok(appInfoDto);
        } else {
            return Response.error(ResultStatus.ILLEGAL_APPCODE);
        }


//        Response<AppInfoDto> appInfoDtoResponse = appOperateService.upGradation(appCode, versionCode);
//        return Response.ok(appInfoDtoResponse.getData());
    }

    private List<JSONObject> geCustomerService(@RequestBody ConfigRequest configRequest) {
        List<JSONObject> list = new ArrayList<>();
        Response<List<UserInfoDto>> userByUserType = userService.getUserByUserType(String.valueOf(UserType.CUSTOMER_SERVICE.getType()));
        if (userByUserType.isSuccess() && userByUserType.getData() != null) {
            List<UserInfoDto> data = userByUserType.getData();
            for (UserInfoDto userInfoDto : data) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("code", configRequest.getCode());
                jsonObject.put("userCode", userInfoDto.getUserCode());
                jsonObject.put("name", userInfoDto.getNickName());
                jsonObject.put("email", userInfoDto.getEmail());
                jsonObject.put("iocn", userInfoDto.getAvatarUrl());
                list.add(jsonObject);
            }
        }
        return list;
    }

    @GetMapping("/iosFunctionFlag")
    @SignIgnore
    @ApiOperation(value = "ios功能是否开启", notes = "ios功能是否开启")
    public Result<Integer> triggerDiscount(@RequestParam @ApiParam("version") String version) {
        if (version.equals("1.0.0")) {
            return Result.ok(1);
        }
        return Result.ok(0);
    }

}